﻿using System.ComponentModel;
using System.Windows;
using Ops.Mpc.Models;

namespace Ops.Mpc.States
{
    public class StateAction : AsyncAction, IStateAction
    {
        #region Fields & Properties
        private bool _isModelValid = true;

        public static readonly DependencyProperty ValidationModelItemNameProperty = DependencyProperty.Register("ValidationModelItemName", typeof(string), typeof(StateAction), null);
        public string ValidationModelItemName
        {
            get
            {
                return (string)this.GetValue(ValidationModelItemNameProperty);
            }

            set
            {
                this.SetValue(ValidationModelItemNameProperty, value);
            }
        }

        public static readonly DependencyProperty NextStateItemNameProperty = DependencyProperty.Register("NextStateItemName", typeof(string), typeof(StateAction), null);
        public string NextStateItemName
        {
            get
            {
                return (string)this.GetValue(NextStateItemNameProperty);
            }

            set
            {
                this.SetValue(NextStateItemNameProperty, value);
            }
        }

        public static readonly DependencyProperty FailStateItemNameProperty = DependencyProperty.Register("FailStateItemName", typeof(string), typeof(StateAction), null);
        public string FailStateItemName
        {
            get
            {
                return (string)this.GetValue(FailStateItemNameProperty);
            }

            set
            {
                this.SetValue(FailStateItemNameProperty, value);
            }
        }

        public static readonly DependencyProperty NextVisualStateProperty = DependencyProperty.Register("NextVisualState", typeof(string), typeof(StateAction), null);
        public string NextVisualState
        {
            get
            {
                return (string)this.GetValue(NextVisualStateProperty);
            }

            set
            {
                this.SetValue(NextVisualStateProperty, value);
            }
        }
        #endregion

        #region Methods
        public override void Start()
        {
            base.Start();

            if (!string.IsNullOrEmpty(this.ValidationModelItemName))
            {
                Model model = this.GetModel(this.ValidationModelItemName);

                if (model != null)
                {
                    this._isModelValid = model.IsValid;
                    model.PropertyChanged += OnModelPropertyChanged;
                    this.UpdateAvailability();
                }
            }

        }

        protected override bool CanExecute()
        {
            if (!string.IsNullOrEmpty(this.ValidationModelItemName))
            {
                Model model = this.GetModel(this.ValidationModelItemName);

                if (model != null)
                {
                    model.Validate();
                    if (!model.IsValid)
                    {
                        return false;
                    }

                }
            }

            return true;

        }

        protected override void OnFinish(ActionResult stateActionResult)
        {
            if (stateActionResult.Successful)
            {
                this.MoveToNextState();

                if (this.NextVisualState != null && this.NextVisualState.Trim().Length > 0)
                    this.Controller.Presenter.SetParentVisualState(this.NextVisualState);
            }
            else
            {
                this.MoveToFailState();
            }
        }



        protected virtual void MoveToNextState()
        {
            if (!string.IsNullOrEmpty(this.NextStateItemName) && this.Controller != null)
                this.Controller.SetCurrentState(this.NextStateItemName);
        }

        protected virtual void MoveToFailState()
        {
            if (!string.IsNullOrEmpty(this.FailStateItemName) && this.Controller != null)
                this.Controller.SetCurrentState(this.FailStateItemName);
        }

        protected void OnModelPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            Model model = sender as Model;
            this._isModelValid = model.IsValid;
            this.UpdateAvailability();
        }

        #endregion
    }

}
